package com.zzl.springboot_mybatis_demo.service.seckill.impl;

import com.gitee.yongzhuzl.commonutil.util.id.IdUtil;
import com.zzl.springboot_mybatis_demo.exception.ResponseException;
import com.zzl.springboot_mybatis_demo.service.seckill.SeckillService;
import com.zzl.springboot_mybatis_demo.util.RedisLock;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * description: 秒杀服务接口实现类
 * @author 朱正磊
 * @date 2019-12-04 10:26:36
 */
@Service
public class SeckillServiceImpl implements SeckillService {

    /**
     * 超时时间 10s
     */
    private static final int TIME_OUT = 10 * 1000;

    @Resource
    private RedisLock redisLock;

    /**
     * 商品库存（总库存）
     */
    private static Map<String, Integer> products;

    /**
     * 库存（变化库存）
     */
    private static Map<String, Integer> stock;

    /**
     * 订单
     */
    private static Map<String, String> orders;

    // 国庆活动，皮蛋粥特价，限量100000份
    // 模拟多张表，商品信息表，库存表，秒杀成功订单表
    static {
        products = new HashMap<>();
        stock = new HashMap<>();
        orders = new HashMap<>();
        products.put("123456", 100000);
        stock.put("123456", 100000);
    }

    /**
     * description：查询秒杀商品信息
     * user 朱正磊
     * time 2019-05-11 23:37
     * @param productId 商品ID
     * @return 返回秒杀商品信息
     */
    private String queryMap(String productId) {
        return "国庆活动，皮蛋粥特价，限量" + products.get(productId) + "份"
                + "，还剩：" + stock.get(productId) + "份"
                + "，该商品成功下单用户数目：" + orders.size() + "人";
    }

    /**
     * description：查询秒杀商品信息
     * user 朱正磊
     * time 2019-05-11 23:36
     * @param productId 商品ID
     * @return 返回秒杀商品信息
     */
    @Override
    public String querySeckillProductInfo(String productId) {
        return this.queryMap(productId);
    }

    /**
     * description：模拟多线程秒杀商品
     * user 朱正磊
     * time 2019-05-11 22:12
     * @param productId 商品ID
     */
    @Override
    public void orderProductMockDiffUser(String productId) {
        //一、加锁
        //值
        long time = System.currentTimeMillis() + TIME_OUT;
        //如果为true表示加锁失败
        if (!redisLock.lock(productId, String.valueOf(time))) {
            throw new ResponseException(100, "哎呦喂，人也太多了吧，请换个姿势再试试~~~");
        }

        //业务逻辑代码
        //1、查询该商品的库存，如果为0则表示该活动已经结束
        //获取当前商品的库存
        int stockNum = stock.get(productId);

        if (stockNum == 0) {
            //如果库存为0，表示当前商品已经卖完
            throw new ResponseException(101, "活动已结束！");
        } else {
            //2、下单（模拟不同用户，根据openid不同进行模拟）
            orders.put(IdUtil.genUniqueId(), productId);

            //3、减库存
            stockNum = stockNum - 1;

            try {
                //线程睡眠0.1s
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //更新库存
            stock.put(productId, stockNum);
        }

        //二、解锁
        redisLock.unlock(productId, String.valueOf(time));
    }

}
